﻿using System;
using System.Collections.Generic;

namespace Atomic.Libraries.Mathematics.Integration
{
	public sealed class GaussLegendreQuadrature
	{
		private static Dictionary<int, Tuple<double[], double[]>> nodes;
		private int n, m;
		private double[] x, w;

		static GaussLegendreQuadrature()
		{
			nodes = new Dictionary<int, Tuple<double[], double[]>>();
			//nodes[2] = Tuple.Create<double[], double[]>(new double[] { 0.57735026918962573 }, new double[] { 1.0 });
			//nodes[3] = Tuple.Create<double[], double[]>(new double[] { 0.0, 0.7745966692414834 }, new double[] { 0.88888888888888884, 0.55555555555555558 });
			//nodes[4] = Tuple.Create<double[], double[]>(new double[] { 0.33998104358485626, 0.86113631159405257 }, new double[] { 0.65214515486254609, 0.34785484513745385 });
			//nodes[5] = Tuple.Create<double[], double[]>(new double[] { 0.0, 0.53846931010568311, 0.906179845938664 }, new double[] { 0.56888888888888889, 0.47862867049936647, 0.23692688505618908 });
			//nodes[6] = Tuple.Create<double[], double[]>(new double[] { 0.2386191860831969, 0.66120938646626448, 0.932469514203152 }, new double[] { 0.46791393457269104, 0.36076157304813861, 0.17132449237917036 });
			//nodes[7] = Tuple.Create<double[], double[]>(new double[] { 0.0, 0.40584515137739718, 0.74153118559939446, 0.94910791234275849 }, new double[] { 0.4179591836734694, 0.38183005050511892, 0.27970539148927664, 0.1294849661688697 });
			//nodes[8] = Tuple.Create<double[], double[]>(new double[] { 0.18343464249564981, 0.525532409916329, 0.79666647741362673, 0.96028985649753618 }, new double[] { 0.362683783378362, 0.31370664587788727, 0.22238103445337448, 0.10122853629037626 });
			//nodes[9] = Tuple.Create<double[], double[]>(new double[] { 0.0, 0.32425342340380892, 0.61337143270059036, 0.83603110732663577, 0.96816023950762609 }, new double[] { 0.33023935500125978, 0.31234707704000286, 0.26061069640293544, 0.1806481606948574, 0.081274388361574412 });
			//nodes[10] = Tuple.Create<double[], double[]>(new double[] { 0.14887433898163122, 0.43339539412924721, 0.67940956829902444, 0.86506336668898454, 0.97390652851717174 }, new double[] { 0.29552422471475287, 0.26926671930999635, 0.21908636251598204, 0.14945134915058059, 0.066671344308688138 });
			//nodes[11] = Tuple.Create<double[], double[]>(new double[] { 0.0, 0.26954315595234496, 0.51909612920681181, 0.73015200557404936, 0.88706259976809532, 0.978228658146057 }, new double[] { 0.27292508677790062, 0.26280454451024665, 0.23319376459199048, 0.18629021092773426, 0.12558036946490461, 0.055668567116173663 });
			//nodes[12] = Tuple.Create<double[], double[]>(new double[] { 0.12523340851146891, 0.36783149899818018, 0.58731795428661748, 0.76990267419430469, 0.90411725637047491, 0.98156063424671924 }, new double[] { 0.24914704581340277, 0.23349253653835481, 0.20316742672306592, 0.16007832854334622, 0.10693932599531843, 0.047175336386511828 });
			//nodes[13] = Tuple.Create<double[], double[]>(new double[] { 0.0, 0.2304583159551348, 0.44849275103644687, 0.64234933944034023, 0.80157809073330988, 0.91759839922297792, 0.98418305471858814 }, new double[] { 0.2325515532308739, 0.22628318026289723, 0.20781604753688851, 0.17814598076194574, 0.13887351021978725, 0.092121499837728452, 0.040484004765315877 });
			//nodes[14] = Tuple.Create<double[], double[]>(new double[] { 0.10805494870734367, 0.31911236892788974, 0.5152486363581541, 0.68729290481168548, 0.827201315069765, 0.92843488366357352, 0.98628380869681231 }, new double[] { 0.21526385346315779, 0.2051984637212956, 0.18553839747793782, 0.15720316715819355, 0.12151857068790319, 0.080158087159760208, 0.03511946033175186 });
			//nodes[15] = Tuple.Create<double[], double[]>(new double[] { 0.0, 0.20119409399743451, 0.39415134707756339, 0.57097217260853883, 0.72441773136017007, 0.84820658341042721, 0.937273392400706, 0.98799251802048538 }, new double[] { 0.20257824192556126, 0.19843148532711158, 0.18616100001556221, 0.16626920581699392, 0.13957067792615432, 0.10715922046717194, 0.070366047488108124, 0.030753241996117269 });
			//nodes[16] = Tuple.Create<double[], double[]>(new double[] { 0.095012509837637441, 0.28160355077925892, 0.45801677765722737, 0.61787624440264377, 0.755404408355003, 0.86563120238783176, 0.9445750230732326, 0.98940093499164994 }, new double[] { 0.1894506104550685, 0.18260341504492358, 0.16915651939500254, 0.14959598881657674, 0.12462897125553388, 0.095158511682492786, 0.062253523938647894, 0.027152459411754096 });
			//nodes[17] = Tuple.Create<double[], double[]>(new double[] { 0.0, 0.17848418149584785, 0.3512317634538763, 0.51269053708647694, 0.65767115921669073, 0.78151400389680137, 0.88023915372698591, 0.9506755217687678, 0.99057547531441736 }, new double[] { 0.17944647035620653, 0.17656270536699264, 0.16800410215645004, 0.15404576107681028, 0.13513636846852548, 0.11188384719340397, 0.085036148317179178, 0.0554595293739872, 0.024148302868547931 });
			//nodes[18] = Tuple.Create<double[], double[]>(new double[] { 0.0847750130417353, 0.25188622569150548, 0.41175116146284263, 0.55977083107394754, 0.69168704306035322, 0.80370495897252314, 0.8926024664975557, 0.95582394957139771, 0.9915651684209309 }, new double[] { 0.1691423829631436, 0.16427648374583273, 0.15468467512626524, 0.14064291467065065, 0.12255520671147846, 0.10094204410628717, 0.076425730254889052, 0.0497145488949698, 0.021616013526483312 });
			//nodes[19] = Tuple.Create<double[], double[]>(new double[] { 0.0, 0.16035864564022537, 0.31656409996362983, 0.46457074137596094, 0.600545304661681, 0.72096617733522939, 0.82271465653714282, 0.9031559036148179, 0.96020815213483, 0.99240684384358435 }, new double[] { 0.1610544498487837, 0.15896884339395434, 0.15276604206585967, 0.1426067021736066, 0.12875396253933621, 0.11156664554733399, 0.09149002162245, 0.069044542737641226, 0.0448142267656996, 0.019461788229726478 });
			//nodes[20] = Tuple.Create<double[], double[]>(new double[] { 0.076526521133497338, 0.22778585114164507, 0.37370608871541955, 0.51086700195082713, 0.636053680726515, 0.7463319064601508, 0.83911697182221878, 0.912234428251326, 0.96397192727791381, 0.99312859918509488 }, new double[] { 0.15275338713072584, 0.14917298647260374, 0.14209610931838204, 0.13168863844917664, 0.11819453196151841, 0.10193011981724044, 0.083276741576704755, 0.062672048334109068, 0.040601429800386939, 0.017614007139152118 });
			//nodes[32] = Tuple.Create<double[], double[]>(new double[] { 0.048307665687738317, 0.14447196158279649, 0.23928736225213706, 0.33186860228212767, 0.42135127613063533, 0.50689990893222936, 0.5877157572407623, 0.66304426693021523, 0.73218211874028971, 0.79448379596794239, 0.84936761373257, 0.89632115576605209, 0.93490607593773967, 0.96476225558750639, 0.98561151154526838, 0.99726386184948157 }, new double[] { 0.0965400885147278, 0.095638720079274861, 0.093844399080804566, 0.091173878695763891, 0.087652093004403811, 0.083311924226946749, 0.078193895787070311, 0.0723457941088485, 0.065822222776361849, 0.058684093478535544, 0.050998059262376175, 0.042835898022226683, 0.034273862913021431, 0.025392065309262059, 0.01627439473090567, 0.0070186100094700964 });
			//nodes[64] = Tuple.Create<double[], double[]>(new double[] { 0.024350292663424433, 0.072993121787799042, 0.12146281929612056, 0.16964442042399283, 0.21742364374000708, 0.26468716220876742, 0.31132287199021097, 0.35722015833766813, 0.40227015796399163, 0.44636601725346409, 0.48940314570705296, 0.53127946401989457, 0.571895646202634, 0.61115535517239328, 0.64896547125465731, 0.68523631305423327, 0.71988185017161077, 0.75281990726053194, 0.78397235894334139, 0.81326531512279754, 0.84062929625258032, 0.86599939815409277, 0.88931544599511414, 0.91052213707850282, 0.92956917213193957, 0.94641137485840277, 0.96100879965205377, 0.973326827789911, 0.983336253884626, 0.99101337147674429, 0.99634011677195533, 0.99930504173577217 }, new double[] { 0.048690957009139724, 0.048575467441503428, 0.048344762234802954, 0.04799938859645831, 0.047540165714830308, 0.04696818281621002, 0.046284796581314416, 0.045491627927418142, 0.044590558163756566, 0.04358372452932345, 0.042473515123653591, 0.041262563242623528, 0.039953741132720343, 0.038550153178615626, 0.037055128540240047, 0.035472213256882386, 0.033805161837141606, 0.03205792835485155, 0.030234657072402478, 0.028339672614259483, 0.026377469715054658, 0.024352702568710874, 0.022270173808383253, 0.020134823153530209, 0.017951715775697343, 0.015726030476024718, 0.013463047896718643, 0.011168139460131128, 0.0088467598263639469, 0.0065044579689783628, 0.0041470332605624679, 0.001783280721696433 });
			//nodes[96] = Tuple.Create<double[], double[]>(new double[] { 0.016276744849602971, 0.04881298513604973, 0.081297495464425565, 0.11369585011066592, 0.14597371465489695, 0.17809688236761861, 0.21003131046056719, 0.24174315616384, 0.27319881259104917, 0.30436494435449635, 0.33520852289262543, 0.36569686147231362, 0.39579764982890858, 0.42547898840730053, 0.454709422167743, 0.48345797392059636, 0.5116941771546677, 0.53938810832435746, 0.56651041856139717, 0.593032364777572, 0.61892584012546858, 0.64416340378496706, 0.66871831004391613, 0.69256453664217155, 0.71567681234896763, 0.73803064374440008, 0.75960234117664749, 0.78036904386743322, 0.80030874413914077, 0.81940031073793163, 0.83762351122818712, 0.85495903343460145, 0.87138850590929651, 0.88689451740242042, 0.9014606353158523, 0.91507142312089806, 0.92771245672230873, 0.93937033975275519, 0.95003271778443765, 0.95968829144874257, 0.96832682846326423, 0.97593917458513646, 0.98251726356301472, 0.98805412632962375, 0.99254390032376261, 0.99598184298720926, 0.99836437586318172, 0.99968950388323075 }, new double[] { 0.03255061449236317, 0.032516118713868836, 0.032447163714064267, 0.032343822568575931, 0.032206204794030253, 0.032034456231992664, 0.031828758894411009, 0.031589330770727168, 0.031316425596861354, 0.031010332586313836, 0.030671376123669148, 0.030299915420827595, 0.029896344136328384, 0.029461089958167905, 0.028994614150555237, 0.028497411065085385, 0.027970007616848334, 0.027412962726029243, 0.026826866725591762, 0.026212340735672413, 0.025570036005349361, 0.02490063322248361, 0.024204841792364692, 0.02348339908592622, 0.022737069658329372, 0.02196664443874435, 0.021172939892191298, 0.020356797154333323, 0.019519081140145021, 0.018660679627411466, 0.017782502316045262, 0.016885479864245174, 0.015970562902562293, 0.015038721026994937, 0.014090941772314861, 0.013128229566961573, 0.01215160467108832, 0.011162102099838499, 0.010160770535008416, 0.009148671230783386, 0.0081268769256987589, 0.0070964707911538652, 0.0060585455042359614, 0.0050142027429275178, 0.0039645543384446867, 0.0029107318179349465, 0.0018539607889469217, 0.00079679206555201244 });
			//nodes[100] = Tuple.Create<double[], double[]>(new double[] { 0.015628984421543084, 0.046871682421591634, 0.078068582813436635, 0.10918920358006111, 0.14020313723611397, 0.17108008053860327, 0.201789864095736, 0.23230248184497396, 0.26258812037150348, 0.292617188038472, 0.32236034390052914, 0.35178852637242169, 0.38087298162462996, 0.40958529167830154, 0.43789740217203149, 0.46578164977335806, 0.49321078920819095, 0.520158019881763, 0.54659701206509415, 0.57250193262138116, 0.59784747024717877, 0.62260886020370776, 0.64676190851412929, 0.670283015603141, 0.693149199355802, 0.71533811757305643, 0.73682808980202075, 0.75759811851970715, 0.77762790964949546, 0.7968978923903145, 0.8153892383391762, 0.83308387988840082, 0.84996452787959131, 0.86601468849716468, 0.88121867938501841, 0.895561644970727, 0.90902957098252968, 0.921609298145334, 0.93328853504307951, 0.944055870136256, 0.95390078292549174, 0.96281365425581555, 0.97078577576370628, 0.9778093584869183, 0.983877540706057, 0.98898439524299175, 0.99312493703744342, 0.99629513473312514, 0.99849195063959584, 0.99971372677344128 }, new double[] { 0.031255423453863354, 0.031224884254849358, 0.031163835696209907, 0.031072337427566515, 0.030950478850490987, 0.030798379031152592, 0.030616186583980447, 0.030404079526454821, 0.030162265105169145, 0.029890979593332832, 0.029590488059912642, 0.029261084110638276, 0.0289030896011252, 0.028516854322395098, 0.028102755659101173, 0.027661198220792389, 0.027192613446576881, 0.026697459183570964, 0.026176219239545676, 0.025629402910208116, 0.02505754448157959, 0.024461202707957052, 0.023840960265968207, 0.023197423185254123, 0.022531220256336273, 0.021843002416247388, 0.021133442112527642, 0.020403232646209433, 0.019653087494435305, 0.018883739613374903, 0.018095940722128116, 0.017290460568323583, 0.016468086176145213, 0.015629621077546004, 0.014775884527441302, 0.013907710703718773, 0.013025947892971542, 0.012131457662979498, 0.011225114023185977, 0.01030780257486897, 0.0093804196536944572, 0.00844387146966897, 0.0074990732554647112, 0.0065469484508453224, 0.005588428003865515, 0.0046244500634221196, 0.0036559612013263754, 0.0026839253715534826, 0.0017093926535181052, 0.00073463449050567174 });
			//nodes[128] = Tuple.Create<double[], double[]>(new double[] { 0.012223698960615764, 0.036663790968733491, 0.061081969604139572, 0.085463640504515492, 0.10979423112764375, 0.13405919946118777, 0.15824404271422493, 0.18233430598533718, 0.20631559090207921, 0.23017356422666, 0.25389396642269429, 0.27746262017790441, 0.30086543887767719, 0.32408843502441337, 0.34711772859763551, 0.369939555349859, 0.39254027503326744, 0.414906379552275, 0.43702450103710416, 0.45888141983355218, 0.48046407240417205, 0.50175955913614445, 0.52275515205117551, 0.54343830241281033, 0.56379664822661812, 0.58381802162876306, 0.60349045615854857, 0.62280219391058489, 0.64174169256230751, 0.660297632272646, 0.67845892244771921, 0.69621470836951438, 0.71355437768358743, 0.73046756674190882, 0.746944166797062, 0.76297433004409476, 0.77854847550641193, 0.79365729476219327, 0.80829175750791371, 0.82244311695564387, 0.83610291506090684, 0.84926298757796892, 0.86191546893954851, 0.87405279695803184, 0.88566771734539718, 0.89675328804915821, 0.9073028834017568, 0.91731019808096048, 0.92676925087894779, 0.93567438827791638, 0.94402028783022018, 0.95180196134126438, 0.95901475785369994, 0.96565436643196523, 0.97171681874713656, 0.97719849146390736, 0.98209610843571848, 0.98640674272458617, 0.99012781849173437, 0.9932571129002129, 0.99579275853498117, 0.997733248625514, 0.99907745997737585, 0.99982488794713187 }, new double[] { 0.024446180196262518, 0.024431569097850044, 0.024402355633849581, 0.024358557264690626, 0.024300200167971867, 0.02422731922281525, 0.024139957989019283, 0.024038168681024052, 0.023922012136703457, 0.023791557781003402, 0.023646883584447616, 0.023488076016535912, 0.023315229994062759, 0.023128448824387027, 0.022927844143686846, 0.022713535850236461, 0.022485652032744968, 0.022244328893799764, 0.021989710668460491, 0.021721949538052076, 0.021441205539208461, 0.02114764646822135, 0.02084144778075115, 0.020522792486960071, 0.020191871042130043, 0.019848881232830861, 0.019494028058706602, 0.019127523609950944, 0.01874958694054471, 0.018360443937331342, 0.017960327185008687, 0.017549475827117706, 0.017128135423111378, 0.016696557801589205, 0.016255000909785187, 0.015803728659399347, 0.015343010768865144, 0.014873122602147314, 0.014394345004166847, 0.013906964132951985, 0.013411271288616333, 0.012907562739267348, 0.012396139543950923, 0.01187730737274028, 0.011351376324080417, 0.010818660739503076, 0.010279479015832158, 0.0097341534150068056, 0.0091830098716608743, 0.00862637779861675, 0.0080645898904860586, 0.0074979819256347285, 0.0069268925668988139, 0.0063516631617071889, 0.0057726375428656983, 0.00519016183267633, 0.004604584256702955, 0.0040162549837386421, 0.0034255260409102157, 0.0028327514714579912, 0.0022382884309626186, 0.0016425030186690294, 0.0010458126793403489, 0.00044938096029209035 });
			//nodes[256] = Tuple.Create<double[], double[]>(new double[] { 0.0061239123751895292, 0.018370818478813666, 0.030614968779979029, 0.0428545265363791, 0.055087655694633982, 0.0673125211657164, 0.079527289100232962, 0.091730127163519554, 0.1039192048105094, 0.1160926935603328, 0.12824876727060711, 0.14038560241137588, 0.1525013783386564, 0.16459427756755385, 0.176662486044902, 0.18870419342138883, 0.20071759332312666, 0.21270088362262596, 0.22465226670913196, 0.23656994975828402, 0.24845214500105667, 0.26029706999194252, 0.2721029478763366, 0.28386800765708176, 0.29559048446013564, 0.30726861979931908, 0.31890066184010629, 0.33048486566241697, 0.34201949352237165, 0.35350281511297, 0.364933107823654, 0.37630865699871641, 0.38762775619451556, 0.39888870743545912, 0.41008982146871653, 0.42122941801762381, 0.43230582603374129, 0.44331738394752734, 0.45426243991759, 0.46513935207847934, 0.47594648878698331, 0.48668222886689033, 0.49734496185218147, 0.507933088228616, 0.51844501967367451, 0.52887917929482231, 0.53923400186605919, 0.54950793406271858, 0.55969943469448113, 0.56980697493656873, 0.579829038559083, 0.58976412215445428, 0.59961073536296827, 0.60936740109633392, 0.61903265575926125, 0.628605049469015, 0.63808314627291141, 0.64746552436372484, 0.65675077629297318, 0.66593750918204853, 0.67502434493116281, 0.684009920426076, 0.692892887742577, 0.70167191434868514, 0.71034568330454328, 0.71891289345997145, 0.72737225964965213, 0.73572251288591783, 0.74396240054911156, 0.752090686575492, 0.76010615164265549, 0.76800759335244562, 0.77579382641132577, 0.78346368280818379, 0.791016011989546, 0.79844968103217073, 0.80576357481299865, 0.81295659617643157, 0.82002766609891709, 0.82697572385081253, 0.83379972715550488, 0.84049865234576271, 0.84707149451729624, 0.853517267679503, 0.85983500490337639, 0.86602375846655455, 0.87208259999548832, 0.87801062060470658, 0.88380693103315833, 0.88947066177761092, 0.89500096322308453, 0.90039700577030357, 0.90565797996014463, 0.910783096595065, 0.91577158685749038, 0.92062270242514654, 0.92533571558331618, 0.92990991933400569, 0.93434462750200309, 0.93863917483781478, 0.94279291711746249, 0.94680523123912752, 0.95067551531662831, 0.95440318876971619, 0.95798769241117809, 0.96142848853073215, 0.96472506097570643, 0.96787691522848951, 0.970883578480743, 0.97374459970437044, 0.97645954971923421, 0.979028021257622, 0.9814496290254644, 0.98372400976031549, 0.985850822286126, 0.98782974756486064, 0.98966048874506518, 0.99134277120758307, 0.99287634260882207, 0.99426097292240967, 0.99549645448109636, 0.99658260202338156, 0.99751925275672082, 0.99830626647300647, 0.99894352584340884, 0.99943093746626144, 0.99976843740926313, 0.99995605001899224 }, new double[] { 0.012247671640289755, 0.01224583436974792, 0.0122421601042728, 0.012236649395040157, 0.012229303068710279, 0.012220122227303969, 0.01220910824803724, 0.012196262783114713, 0.012181587759481772, 0.012165085378535502, 0.01214675811579446, 0.012126608720527321, 0.012104640215340462, 0.012080855895724545, 0.01205525932956015, 0.012027854356582572, 0.011998645087805812, 0.011967635904905894, 0.011934831459563562, 0.01190023667276649, 0.011863856734071079, 0.011825697100823977, 0.011785763497343426, 0.01174406191406055, 0.011700598606620741, 0.011655380094945243, 0.011608413162253107, 0.011559704854043635, 0.011509262477039497, 0.011457093598090639, 0.011403206043039186, 0.011347607895545491, 0.01129030749587551, 0.011231313439649669, 0.01117063457655345, 0.011108280009009843, 0.0110442590908139, 0.010978581425729571, 0.010911256866049039, 0.010842295511114796, 0.010771707705804627, 0.010699504038979785, 0.010625695341896561, 0.010550292686581482, 0.010473307384170403, 0.010394750983211729, 0.010314635267934014, 0.010232972256478219, 0.010149774199094866, 0.010065053576306384, 0.0099788230970349109, 0.0098910956966958286, 0.0098018845352573283, 0.00971120299526628, 0.0096190646798407272, 0.0095254834106292853, 0.0094304732257377531, 0.00933404837762327, 0.0092362233309563023, 0.0091370127604508064, 0.0090364315486628731, 0.0089344947837582071, 0.00883121775724875, 0.0087266159616988075, 0.008620705088401015, 0.00851350102502249, 0.0084050198532215365, 0.0082952778462352262, 0.00818429146643827, 0.008072077362873499, 0.0079586523687543483, 0.0078440334989397127, 0.0077282379473815558, 0.0076112830845456595, 0.0074931864548058837, 0.0073739657738123464, 0.0072536389258339136, 0.00713222396107539, 0.0070097390929698229, 0.0068862026954463204, 0.0067616333001737985, 0.0066360495937810649, 0.0065094704150536606, 0.006381914752107881, 0.0062534017395424009, 0.0061239506555679328, 0.0059935809191153386, 0.0058623120869226528, 0.0057301638506014373, 0.0055971560336829105, 0.00546330858864431, 0.0053286415939159306, 0.0051931752508692806, 0.0050569298807868427, 0.004919925921813866, 0.0047821839258926913, 0.00464372455568006, 0.0045045685814478972, 0.0043647368779680569, 0.0042242504213815361, 0.0040831302860526685, 0.0039413976414088333, 0.0037990737487662578, 0.0036561799581425023, 0.0035127377050563073, 0.003368768507315551, 0.0032242939617941981, 0.0030793357411993375, 0.0029339155908297168, 0.0027880553253277068, 0.0026417768254274904, 0.0024951020347037068, 0.0023480529563273118, 0.0022006516498399107, 0.0020529202279661431, 0.0019048808534997185, 0.00175655573633073, 0.0016079671307493272, 0.0014591373333107333, 0.0013100886819025043, 0.0011608435575677248, 0.0010114243932084406, 0.000861853701420089, 0.00071215416347332071, 0.00056234895403140981, 0.00041246325442617632, 0.00026253494429644592, 0.00011278901782227218 });
			//nodes[512] = Tuple.Create<double[], double[]>(new double[] { 0.0030649621851593961, 0.00919477138643291, 0.015324235084898186, 0.021453122959774876, 0.027581204711919785, 0.033708250072480593, 0.039834028811548447, 0.045958310746809061, 0.05208086575219207, 0.05820146376651824, 0.064319874802144239, 0.0704358689536047, 0.07654921640625105, 0.082659687444887164, 0.088767052462401033, 0.094871081968392543, 0.10097154659779678, 0.10706821711950266, 0.11316086444496654, 0.1192492596368204, 0.12533317391747448, 0.13141237867771371, 0.13748664548528805, 0.14355574609349603, 0.14961945244976127, 0.15567753670420187, 0.1617297712181921, 0.16777592857291612, 0.17381578157791344, 0.17984910327961592, 0.1858756669698757, 0.19189524619448403, 0.19790761476168048, 0.20391254675065237, 0.20990981652002394, 0.21589919871633503, 0.22188046828250904, 0.22785340046630959, 0.23381777082878588, 0.23977335525270618, 0.24571992995097924, 0.25165727147506334, 0.25758515672336263, 0.2635033629496103, 0.26941166777123859, 0.27530984917773504, 0.28119768553898467, 0.28707495561359797, 0.29294143855722443, 0.29879691393085073, 0.30464116170908423, 0.31047396228842045, 0.31629509649549487, 0.32210434559531881, 0.32790149129949842, 0.33368631577443714, 0.339458601649521, 0.34521813202528667, 0.35096469048157142, 0.35669806108564561, 0.36241802840032644, 0.36812437749207311, 0.37381689393906337, 0.37949536383925053, 0.3851595738184011, 0.39080931103811251, 0.39644436320381055, 0.40206451857272696, 0.40766956596185555, 0.41325929475588763, 0.41883349491512628, 0.42439195698337867, 0.42993447209582658, 0.43546083198687474, 0.44097082899797668, 0.44646425608543749, 0.4519409068281941, 0.45740057543557128, 0.4628430567550148, 0.46826814627980007, 0.47367564015671665, 0.47906533519372846, 0.48443702886760864, 0.48979051933154988, 0.49512560542274864, 0.50044208666996437, 0.50573976330105219, 0.51101843625046994, 0.51627790716675748, 0.52151797841999081, 0.52673845310920775, 0.53193913506980661, 0.5371198288809178, 0.54228033987274615, 0.54742047413388661, 0.55254003851861022, 0.557638840654122, 0.562716688947789, 0.56777339259434068, 0.5728087615830374, 0.57782260670481111, 0.58281473955937446, 0.58778497256230078, 0.59273311895207215, 0.59765899279709767, 0.60256240900269942, 0.60744318331806835, 0.612301132343187, 0.6171360735357212, 0.62194782521787939, 0.62673620658323925, 0.6315010377035416, 0.63624213953545172, 0.64095933392728643, 0.645652443625709, 0.65032129228238933, 0.65496570446063029, 0.65958550564196028, 0.66418052223269053, 0.66875058157043843, 0.67329551193061521, 0.67781514253287878, 0.68230930354755093, 0.68677782610199911, 0.6912205422869816, 0.695637285162957, 0.70002788876635724, 0.70439218811582383, 0.70873001921840706, 0.71304121907572848, 0.71732562569010527, 0.72158307807063793, 0.72581341623925932, 0.73001648123674656, 0.734192115128693, 0.73834016101144417, 0.74246046301799229, 0.74655286632383411, 0.75061721715278806, 0.75465336278277251, 0.7586611515515449, 0.76264043286240024, 0.76659105718982989, 0.77051287608514052, 0.77440574218203173, 0.77826950920213378, 0.78210403196050415, 0.785909166371083, 0.78968476945210719, 0.793430699331483, 0.7971468152521175, 0.80083297757720706, 0.80448904779548458, 0.80811488852642432, 0.81171036352540427, 0.81527533768882487, 0.81880967705918684, 0.82231324883012358, 0.8257859213513925, 0.82922756413382126, 0.83263804785421136, 0.83601724436019742, 0.83936502667506274, 0.8426812690025105, 0.84596584673139064, 0.84921863644038265, 0.85243951590263267, 0.85562836409034648, 0.85878506117933739, 0.861909488553529, 0.8650015288094115, 0.86806106576045394, 0.87108798444146984, 0.87408217111293729, 0.8770435132652723, 0.87997189962305711, 0.882867220149221, 0.8857293660491754, 0.88855822977490184, 0.89135370502899269, 0.8941156867686465, 0.89684407120961385, 0.8995387558300979, 0.90219963937460679, 0.904826621857758, 0.9074196045680355, 0.90997849007149922, 0.912503182215446, 0.91499358613202286, 0.91744960824179111, 0.91987115625724358, 0.92225813918627186, 0.92461046733558561, 0.92692805231408282, 0.92921080703617109, 0.93145864572504034, 0.93367148391588539, 0.93584923845908052, 0.93799182752330312, 0.94009917059860937, 0.94217118849945891, 0.9442078033676905, 0.946208938675448, 0.94817451922805507, 0.95010447116684194, 0.95199872197191981, 0.953857200464906, 0.95567983681159885, 0.95746656252460194, 0.9592173104658972, 0.96093201484936774, 0.9626106112432703, 0.964253036572656, 0.96585922912174071, 0.96742912853622376, 0.96896267582555662, 0.97045981336515874, 0.97192048489858363, 0.97334463553963246, 0.974732211774417, 0.97608316146337026, 0.97739743384320588, 0.97867497952882632, 0.97991575051517821, 0.98111970017905714, 0.98228678328085961, 0.983416955966284, 0.98451017576797839, 0.98556640160713793, 0.98658559379504918, 0.98756771403458288, 0.988512725421635, 0.9894205924465157, 0.99029128099528685, 0.99112475835104807, 0.99192099319517146, 0.99267995560848654, 0.99340161707241481, 0.99408595047005588, 0.99473293008722818, 0.99534253161346575, 0.99591473214297721, 0.99644951017557737, 0.99694684561760383, 0.99740671978284978, 0.99782911539356289, 0.9982140165816128, 0.99856140889003975, 0.99887127927544939, 0.99914361611237823, 0.99937840920259924, 0.99957564979831082, 0.9997353306710427, 0.99985744636997942, 0.99994199460684563, 0.99998899098438188 }, new double[] { 0.006129905175405786, 0.0061296748380364986, 0.0061292141719530837, 0.0061285231944655325, 0.0061276019315380228, 0.0061264504177879365, 0.0061250686964845653, 0.0061234568195474804, 0.0061216148475445832, 0.0061195428496898293, 0.0061172409038406286, 0.0061147090964949174, 0.00611194752278791, 0.0061089562864885235, 0.0061057354999954792, 0.0061022852843330777, 0.0060986057691466526, 0.0060946970926976981, 0.0060905594018586728, 0.0060861928521074842, 0.0060815976075216426, 0.0060767738407720984, 0.0060717217331167509, 0.0060664414743936421, 0.0060609332630138174, 0.0060551973059538768, 0.00604923381874819, 0.0060430430254808038, 0.00603662515877702, 0.006029980459794651, 0.0060231091782149632, 0.0060160115722332928, 0.0060086879085493421, 0.0060011384623571608, 0.0059933635173348033, 0.0059853633656336705, 0.0059771383078675308, 0.0059686886531012256, 0.0059600147188390547, 0.0059511168310128456, 0.0059419953239697081, 0.0059326505404594674, 0.00592308283162179, 0.0059132925569729856, 0.0059032800843924968, 0.0058930457901090793, 0.0058825900586866623, 0.0058719132830099005, 0.0058610158642694067, 0.0058498982119466816, 0.0058385607437987227, 0.0058270038858423316, 0.0058152280723381012, 0.005803233745774101, 0.0057910213568492467, 0.0057785913644563718, 0.0057659442356649739, 0.0057530804457036752, 0.0057400004779423553, 0.0057267048238739959, 0.0057131939830962087, 0.00569946846329246, 0.0056855287802130014, 0.0056713754576554832, 0.0056570090274452745, 0.00564243002941548, 0.005627639011386654, 0.0056126365291462171, 0.00559742314642757, 0.005581999434888912, 0.0055663659740917606, 0.0055505233514791712, 0.0055344721623536665, 0.0055182130098548679, 0.0055017465049368277, 0.0054850732663450762, 0.0054681939205933686, 0.0054511091019401456, 0.0054338194523647, 0.005416325621543051, 0.0053986282668235363, 0.0053807280532021081, 0.0053626256532973452, 0.0053443217473251835, 0.0053258170230733488, 0.0053071121758755183, 0.0052882079085851911, 0.0052691049315492762, 0.0052498039625814025, 0.0052303057269349447, 0.0052106109572757726, 0.0051907203936547193, 0.0051706347834797736, 0.0051503548814879957, 0.0051298814497171561, 0.0051092152574771033, 0.0050883570813208519, 0.00506730770501541, 0.00504606791951232, 0.0050246385229179447, 0.0050030203204634738, 0.0049812141244746679, 0.0049592207543413336, 0.0049370410364865365, 0.0049146758043355438, 0.0048921258982845108, 0.0048693921656689, 0.0048464754607316432, 0.004823376644591041, 0.0048000965852084071, 0.0047766361573554515, 0.0047529962425814131, 0.0047291777291799311, 0.0047051815121556696, 0.0046810084931906857, 0.0046566595806105462, 0.0046321356893501984, 0.004607437740919592, 0.0045825666633690478, 0.00455752339125439, 0.0045323088656018251, 0.0045069240338725851, 0.0044813698499273262, 0.0044556472739902819, 0.0044297572726131867, 0.0044037008186389552, 0.0043774788911651241, 0.004351092475507066, 0.0043245425631609612, 0.0042978301517665445, 0.0042709562450696159, 0.0042439218528843243, 0.0042167279910552214, 0.0041893756814190934, 0.0041618659517665612, 0.0041341998358034645, 0.0041063783731120126, 0.0040784026091117281, 0.0040502735950201582, 0.004021992387813378, 0.0039935600501862746, 0.0039649776505126088, 0.0039362462628048786, 0.0039073669666739551, 0.0038783408472885172, 0.0038491689953342781, 0.0038198525069729982, 0.003790392483801296, 0.003760790032809257, 0.0037310462663388338, 0.0037011623020420533, 0.0036711392628390144, 0.0036409782768756986, 0.0036106804774815745, 0.0035802470031270142, 0.0035496789973805134, 0.0035189776088657204, 0.0034881439912182763, 0.0034571793030424647, 0.003426084707867677, 0.0033948613741046916, 0.00336351047500177, 0.0033320331886005682, 0.0033004306976918752, 0.0032687041897711644, 0.003236854856993974, 0.0032048838961311115, 0.0031727925085236813, 0.003140581900037946, 0.003108253281020012, 0.0030758078662503521, 0.0030432468748981577, 0.0030105715304755269, 0.0029777830607914902, 0.0029448826979058761, 0.0029118716780830124, 0.0028787512417452737, 0.0028455226334264724, 0.0028121871017250922, 0.0027787458992573726, 0.0027452002826102392, 0.0027115515122940878, 0.0026778008526954179, 0.0026439495720293237, 0.0026099989422918393, 0.0025759502392121414, 0.002541804742204615, 0.0025075637343207752, 0.0024732285022010581, 0.0024388003360264737, 0.0024042805294701248, 0.0023696703796485981, 0.0023349711870732236, 0.0023001842556012067, 0.0022653108923866346, 0.0022303524078313604, 0.002195310115535763, 0.0021601853322493884, 0.0021249793778214728, 0.0020896935751513472, 0.0020543292501387315, 0.0020188877316339115, 0.00198337035138781, 0.0019477784440019431, 0.0019121133468782765, 0.0018763764001689719, 0.0018405689467260314, 0.0018046923320508429, 0.0017687479042436242, 0.0017327370139527706, 0.0016966610143241089, 0.0016605212609500561, 0.0016243191118186897, 0.0015880559272627268, 0.0015517330699084185, 0.0015153519046243599, 0.0014789137984702173, 0.001442420120645377, 0.0014058722424375165, 0.0013692715371711026, 0.0013326193801558191, 0.0012959171486349257, 0.0012591662217335559, 0.001222367980406954, 0.0011855238073886604, 0.0011486350871386503, 0.0011117032057914331, 0.0010747295511041248, 0.0010377155124045075, 0.001000662480539091, 0.00096357184782120569, 0.00092644500797915827, 0.00088928335610450053, 0.000852088288600481, 0.000814861203130782, 0.00077760349856869726, 0.00074031657494698193, 0.00070300183340874119, 0.00066566067615993435, 0.00062829450642443586, 0.000590904728403223, 0.00055349274724038951, 0.00051605996900076746, 0.00047860780066795092, 0.00044113765017954055, 0.00040365092653331987, 0.00036614904003562685, 0.00032863340285233341, 0.00029110543025148852, 0.00025356654357058654, 0.00021601817797699087, 0.0001784618055459533, 0.00014089901738819849, 0.00010333190349691323, 6.57657316592402e-05, 2.8252637373934691e-05 });
			//nodes[1024] = Tuple.Create<double[], double[]>(new double[] { 0.0015332313560626385, 0.0045996796509132605, 0.0076660846940754864, 0.01073241765154228, 0.013798649689984441, 0.016864751977021728, 0.019930695681493978, 0.022996451973732214, 0.026061992025829733, 0.029127287011913174, 0.032192308108413586, 0.035257026494337457, 0.038321413351537714, 0.041385439864984719, 0.044449077223037217, 0.047512296617713251, 0.050575069244961066, 0.053637366304929941, 0.056699159002241012, 0.059760418546258035, 0.0628211161513581, 0.065881223037202327, 0.0689407104290065, 0.0719995495578116, 0.075057711660754381, 0.07811516798133776, 0.0811718897697013, 0.084227848282891524, 0.087283014785132132, 0.090337360548094311, 0.0933908568511668, 0.096443474981725938, 0.099495186235405764, 0.10254596191636782, 0.10559577333757099, 0.10864459182104134, 0.11169238869814169, 0.11473913530984124, 0.11778480300698502, 0.12082936315056332, 0.12387278711198098, 0.12691504627332656, 0.12995611202764151, 0.13299595577918905, 0.13603454894372319, 0.1390718629487574, 0.14210786923383342, 0.14514253925078968, 0.14817584446402979, 0.15120775635079087, 0.15423824640141184, 0.15726728611960133, 0.1602948470227058, 0.16332090064197727, 0.166345418522841, 0.16936837222516316, 0.1723897333235182, 0.17540947340745611, 0.1784275640817696, 0.18144397696676109, 0.1844586836985096, 0.18747165592913745, 0.19048286532707678, 0.19349228357733605, 0.19649988238176616, 0.19950563345932665, 0.20250950854635161, 0.20551147939681544, 0.20851151778259841, 0.21150959549375217, 0.21450568433876496, 0.21749975614482669, 0.220491782758094, 0.22348173604395472, 0.22646958788729266, 0.22945531019275192, 0.23243887488500103, 0.23542025390899704, 0.23839941923024918, 0.24137634283508258, 0.24435099673090174, 0.24732335294645358, 0.25029338353209063, 0.25326106056003372, 0.25622635612463474, 0.25918924234263879, 0.26214969135344668, 0.26510767531937668, 0.26806316642592637, 0.27101613688203413, 0.27396655892034061, 0.27691440479744966, 0.27985964679418929, 0.28280225721587232, 0.28574220839255682, 0.2886794726793061, 0.29161402245644907, 0.29454583012983954, 0.29747486813111584, 0.30040110891796024, 0.30332452497435752, 0.30624508881085416, 0.30916277296481653, 0.31207755000068921, 0.31498939251025304, 0.31789827311288271, 0.3208041644558044, 0.32370703921435279, 0.32660687009222816, 0.32950362982175291, 0.33239729116412814, 0.33528782690968961, 0.3381752098781638, 0.34105941291892328, 0.34394040891124206, 0.34681817076455079, 0.3496926714186912, 0.35256388384417087, 0.35543178104241713, 0.35829633604603106, 0.3611575219190411, 0.36401531175715629, 0.36686967868801912, 0.3697205958714585, 0.37256803649974196, 0.37541197379782765, 0.37825238102361636, 0.38108923146820278, 0.38392249845612669, 0.38675215534562385, 0.38957817552887647, 0.39240053243226336, 0.39521919951661, 0.39803415027743788, 0.40084535824521378, 0.40365279698559875, 0.40645644009969667, 0.40925626122430225, 0.4120522340321493, 0.41484433223215805, 0.41763252956968239, 0.42041679982675689, 0.423197116822343, 0.42597345441257578, 0.4287457864910092, 0.43151408698886179, 0.43427832987526205, 0.43703848915749277, 0.43979453888123587, 0.44254645313081609, 0.44529420602944486, 0.44803777173946374, 0.45077712446258711, 0.45351223844014493, 0.45624308795332497, 0.4589696473234145, 0.46169189091204188, 0.46440979312141761, 0.4671233283945751, 0.46983247121561084, 0.4725371961099244, 0.47523747764445795, 0.47793329042793559, 0.48062460911110183, 0.48331140838696007, 0.48599366299101071, 0.48867134770148846, 0.4913444373395997, 0.49401290676975912, 0.49667673089982628, 0.49933588468134116, 0.50199034310976021, 0.50464008122469084, 0.507285074110127, 0.50992529689468258, 0.51256072475182579, 0.51519133290011243, 0.5178170966034189, 0.52043799117117517, 0.52305399195859636, 0.52566507436691468, 0.5282712138436112, 0.530872385882646, 0.53346856602468917, 0.53605972985735029, 0.53864585301540879, 0.541226911181042, 0.54380288008405464, 0.54637373550210688, 0.54893945326094162, 0.55150000923461262, 0.55405537934571047, 0.55660553956558978, 0.55915046591459472, 0.56169013446228433, 0.56422452132765821, 0.56675360267938035, 0.56927735473600349, 0.571795753766193, 0.57430877608894959, 0.57681639807383234, 0.57931859614118064, 0.58181534676233637, 0.58430662645986431, 0.58679241180777375, 0.58927267943173833, 0.591747406009316, 0.59421656827016811, 0.59668014299627836, 0.59913810702217152, 0.60159043723513017, 0.60403711057541354, 0.60647810403647284, 0.60891339466516869, 0.61134295956198659, 0.613766775881252, 0.6161848208313454, 0.61859707167491673, 0.6210035057290989, 0.62340410036572158, 0.62579883301152306, 0.62818768114836343, 0.630570622313436, 0.6329476340994783, 0.63531869415498321, 0.63768378018440863, 0.64004286994838766, 0.64239594126393729, 0.644742972004667, 0.64708394010098746, 0.64941882354031721, 0.65174760036729, 0.65407024868396135, 0.6563867466500144, 0.65869707248296527, 0.66100120445836763, 0.66329912091001741, 0.66559080023015638, 0.667876220869675, 0.67015536133831555, 0.672428200204874, 0.6746947160974015, 0.67695488770340517, 0.67920869377004889, 0.681456113104353, 0.68369712457339327, 0.68593170710450035, 0.6881598396854568, 0.690381501364696, 0.69259667125149793, 0.69480532851618659, 0.69700745239032513, 0.69920302216691155, 0.70139201720057354, 0.7035744169077619, 0.70575020076694506, 0.70791934831880132, 0.71008183916641154, 0.71223765297545083, 0.71438676947437973, 0.71652916845463521, 0.71866482977082, 0.72079373334089258, 0.72291585914635592, 0.72503118723244542, 0.727139697708317, 0.72924137074723372, 0.73133618658675259, 0.73342412552891012, 0.73550516794040743, 0.73757929425279534, 0.73964648496265806, 0.74170672063179643, 0.74375998188741121, 0.74580624942228479, 0.74784550399496275, 0.749877726429935, 0.75190289761781626, 0.7539209985155253, 0.755932010146464, 0.75793591360069645, 0.759932690035126, 0.76192232067367283, 0.76390478680745055, 0.76588006979494194, 0.76784815106217419, 0.76980901210289387, 0.77176263447874072, 0.77370899981942076, 0.77564808982287992, 0.777579886255475, 0.779504370952146, 0.78142152581658642, 0.78333133282141365, 0.7852337740083386, 0.78712883148833424, 0.78901648744180386, 0.79089672411874923, 0.7927695238389364, 0.79463486899206315, 0.79649274203792353, 0.79834312550657383, 0.80018600199849566, 0.80202135418476062, 0.80384916480719282, 0.805669416678531, 0.80748209268259052, 0.80928717577442377, 0.81108464898048116, 0.81287449539877021, 0.81465669819901443, 0.816431240622812, 0.81819810598379317, 0.81995727766777682, 0.82170873913292719, 0.82345247390990917, 0.82518846560204329, 0.82691669788545974, 0.828637154509252, 0.83034981929562945, 0.83205467614006978, 0.83375170901147033, 0.83544090195229859, 0.83712223907874284, 0.83879570458086061, 0.84046128272272824, 0.84211895784258839, 0.84376871435299716, 0.84541053674097122, 0.847044409568133, 0.84867031747085653, 0.85028824516041146, 0.85189817742310681, 0.85350009912043434, 0.8550939951892107, 0.856679850641719, 0.85825765056585, 0.859827380125242, 0.86138902455942057, 0.8629425691839373, 0.864487999390508, 0.86602530064714989, 0.867554458498318, 0.86907545856504187, 0.87058828654505993, 0.87209292821295459, 0.87358936942028542, 0.87507759609572289, 0.8765575942451802, 0.87802934995194493, 0.87949284937680983, 0.88094807875820347, 0.882395024412319, 0.88383367273324309, 0.88526401019308376, 0.886686023342098, 0.88809969880881767, 0.88950502330017556, 0.89090198360163031, 0.89229056657729056, 0.8936707591700388, 0.895042548401654, 0.89640592137293307, 0.89776086526381327, 0.89910736733349172, 0.900445414920546, 0.90177499544305251, 0.90309609639870536, 0.90440870536493356, 0.90571280999901782, 0.90700839803820721, 0.90829545729983352, 0.90957397568142651, 0.91084394116082756, 0.91210534179630265, 0.91335816572665451, 0.91460240117133451, 0.91583803643055317, 0.91706505988539, 0.9182834599979034, 0.91949322531123845, 0.92069434444973519, 0.921886806119035, 0.92307059910618727, 0.924245712279755, 0.92541213458991878, 0.92656985506858125, 0.92771886282947, 0.92885914706824024, 0.929990697062576, 0.93111350217229094, 0.93222755183942885, 0.93333283558836266, 0.93442934302589287, 0.93551706384134525, 0.93659598780666808, 0.9376661047765279, 0.93872740468840554, 0.9397798775626901, 0.94082351350277293, 0.941858302695141, 0.942884235409469, 0.9439013019987107, 0.9449094928991898, 0.94590879863068988, 0.94689920979654352, 0.94788071708372057, 0.94885331126291583, 0.94981698318863583, 0.95077172379928487, 0.95171752411724986, 0.95265437524898544, 0.95358226838509685, 0.95450119480042328, 0.95541114585411979, 0.95631211298973851, 0.95720408773530885, 0.958087061703418, 0.95896102659128846, 0.95982597418085758, 0.96068189633885381, 0.96152878501687344, 0.96236663225145636, 0.9631954301641612, 0.9640151709616388, 0.964825846935706, 0.965627450463418, 0.96641997400713975, 0.9672034101146173, 0.96797775141904763, 0.96874299063914771, 0.96949912057922361, 0.97024613412923721, 0.97098402426487407, 0.97171278404760886, 0.97243240662477048, 0.97314288522960724, 0.97384421318134962, 0.97453638388527375, 0.97521939083276288, 0.97589322760136921, 0.97655788785487352, 0.97721336534334569, 0.9778596539032024, 0.97849674745726611, 0.97912464001482125, 0.97974332567167144, 0.98035279861019442, 0.980953053099397, 0.98154408349496858, 0.98212588423933511, 0.9826984498617104, 0.98326177497814782, 0.98381585429159135, 0.98436068259192488, 0.98489625475602149, 0.98542256574779163, 0.9859396106182301, 0.98644738450546321, 0.9869458826347941, 0.98743510031874737, 0.98791503295711414, 0.988385676036994, 0.98884702513283862, 0.98929907590649269, 0.98974182410723488, 0.9901752655718179, 0.99059939622450766, 0.99101421207712126, 0.9914197092290653, 0.99181588386737152, 0.99220273226673372, 0.99258025078954182, 0.99294843588591708, 0.99330728409374458, 0.9936567920387066, 0.99399695643431363, 0.99432777408193618, 0.99464924187083414, 0.99496135677818653, 0.99526411586912, 0.99555751629673628, 0.99584155530213958, 0.99611623021446194, 0.9963815384508895, 0.9966374775166863, 0.99688404500521843, 0.9971212385979773, 0.99734905606460145, 0.9975674952628989, 0.99777655413886812, 0.99797623072671859, 0.99816652314889154, 0.99834742961608, 0.9985189484272492, 0.99868107796965822, 0.99883381671888261, 0.99897716323884034, 0.9991111161818228, 0.99923567428853477, 0.9993508363881507, 0.99945660139840009, 0.99955296832570706, 0.99963993626543823, 0.99971750440237472, 0.999785672011689, 0.99984443846117121, 0.999893803216942, 0.99993376586061777, 0.99996432615388942, 0.99998548438502843, 0.99999724505455845 }, new double[] { 0.0030664603092439083, 0.0030664314747171936, 0.0030663738059349007, 0.0030662873034393006, 0.0030661719680437935, 0.0030660278008329002, 0.003065854803162254, 0.0030656529766585846, 0.0030654223232197074, 0.0030651628450145008, 0.00306487454448289, 0.0030645574243358211, 0.0030642114875552365, 0.0030638367373940481, 0.0030634331773761051, 0.0030630008112961606, 0.003062539643219838, 0.0030620496774835908, 0.0030615309186946631, 0.0030609833717310454, 0.0030604070417414287, 0.0030598019341451571, 0.0030591680546321752, 0.0030585054091629765, 0.0030578140039685463, 0.0030570938455503028, 0.0030563449406800368, 0.0030555672963998473, 0.003054760920022076, 0.0030539258191292374, 0.0030530620015739485, 0.0030521694754788559, 0.0030512482492365566, 0.0030502983315095211, 0.0030493197312300123, 0.0030483124576, 0.0030472765200910755, 0.0030462119284443618, 0.0030451186926704231, 0.003043996823049169, 0.0030428463301297591, 0.0030416672247305038, 0.0030404595179387623, 0.0030392232211108373, 0.003037958345871871, 0.0030366649041157321, 0.0030353429080049068, 0.0030339923699703839, 0.0030326133027115368, 0.0030312057191960043, 0.0030297696326595704, 0.0030283050566060382, 0.0030268120048071025, 0.0030252904913022224, 0.0030237405303984864, 0.003022162136670481, 0.0030205553249601515, 0.0030189201103766631, 0.0030172565082962582, 0.0030155645343621132, 0.0030138442044841908, 0.0030120955348390886, 0.0030103185418698906, 0.0030085132422860094, 0.0030066796530630303, 0.0030048177914425516, 0.0030029276749320229, 0.0030010093213045804, 0.002999062748598878, 0.0029970879751189203, 0.0029950850194338896, 0.0029930539003779691, 0.0029909946370501703, 0.0029889072488141488, 0.002986791755298025, 0.0029846481763941986, 0.0029824765322591621, 0.0029802768433133103, 0.0029780491302407487, 0.0029757934139891004, 0.0029735097157693059, 0.0029711980570554276, 0.0029688584595844443, 0.00296649094535605, 0.0029640955366324437, 0.0029616722559381234, 0.0029592211260596711, 0.0029567421700455419, 0.002954235411205844, 0.0029517008731121219, 0.0029491385795971333, 0.0029465485547546261, 0.0029439308229391105, 0.0029412854087656321, 0.0029386123371095379, 0.0029359116331062443, 0.0029331833221509997, 0.0029304274298986464, 0.0029276439822633784, 0.0029248330054184994, 0.0029219945257961746, 0.0029191285700871841, 0.00291623516524067, 0.0029133143384638856, 0.0029103661172219363, 0.0029073905292375237, 0.0029043876024906841, 0.0029013573652185262, 0.0028982998459149644, 0.0028952150733304507, 0.0028921030764717066, 0.0028889638846014472, 0.0028857975272381085, 0.002882604034155569, 0.0028793834353828696, 0.0028761357612039303, 0.0028728610421572686, 0.0028695593090357079, 0.0028662305928860913, 0.0028628749250089892, 0.002859492336958403, 0.0028560828605414712, 0.0028526465278181671, 0.0028491833711010014, 0.0028456934229547136, 0.0028421767161959702, 0.0028386332838930533, 0.0028350631593655508, 0.0028314663761840422, 0.0028278429681697845, 0.0028241929693943926, 0.0028205164141795196, 0.0028168133370965339, 0.002813083772966195, 0.0028093277568583242, 0.0028055453240914763, 0.0028017365102326075, 0.00279790135109674, 0.0027940398827466266, 0.00279015214149241, 0.0027862381638912824, 0.0027822979867471419, 0.0027783316471102449, 0.0027743391822768605, 0.0027703206297889169, 0.0027662760274336498, 0.0027622054132432476, 0.0027581088254944918, 0.0027539863027084, 0.0027498378836498605, 0.0027456636073272707, 0.0027414635129921674, 0.0027372376401388603, 0.00273298602850406, 0.0027287087180665019, 0.0027244057490465748, 0.0027200771619059379, 0.0027157229973471444, 0.0027113432963132558, 0.0027069380999874587, 0.0027025074497926765, 0.0026980513873911807, 0.0026935699546841987, 0.0026890631938115196, 0.0026845311471510981, 0.0026799738573186566, 0.0026753913671672832, 0.0026707837197870311, 0.00266615095850451, 0.002661493126882482, 0.0026568102687194489, 0.002652102428049244, 0.0026473696491406138, 0.0026426119764968062, 0.0026378294548551483, 0.0026330221291866272, 0.0026281900446954672, 0.0026233332468187059, 0.0026184517812257641, 0.0026135456938180188, 0.0026086150307283703, 0.002603659838320809, 0.0025986801631899797, 0.0025936760521607428, 0.0025886475522877337, 0.0025835947108549212, 0.0025785175753751631, 0.0025734161935897586, 0.0025682906134679986, 0.0025631408832067176, 0.0025579670512298372, 0.0025527691661879127, 0.0025475472769576745, 0.0025423014326415696, 0.0025370316825672995, 0.0025317380762873562, 0.0025264206635785555, 0.0025210794944415704, 0.00251571461910046, 0.0025103260880021986, 0.002504913951816198, 0.0024994782614338354, 0.0024940190679679708, 0.00248853642275247, 0.0024830303773417197, 0.0024775009835101424, 0.0024719482932517114, 0.00246637235877946, 0.0024607732325249922, 0.0024551509671379883, 0.0024495056154857108, 0.0024438372306525066, 0.0024381458659393082, 0.0024324315748631324, 0.0024266944111565772, 0.0024209344287673159, 0.0024151516818575907, 0.002409346224803704, 0.0024035181121955041, 0.0023976673988358758, 0.0023917941397402216, 0.0023858983901359479, 0.0023799802054619416, 0.0023740396413680529, 0.0023680767537145684, 0.0023620915985716885, 0.0023560842322189993, 0.0023500547111449423, 0.0023440030920462854, 0.0023379294318275875, 0.002331833787600665, 0.0023257162166840538, 0.0023195767766024714, 0.0023134155250862753, 0.0023072325200709197, 0.0023010278196964108, 0.0022948014823067622, 0.0022885535664494425, 0.0022822841308748286, 0.0022759932345356509, 0.0022696809365864387, 0.0022633472963829661, 0.002256992373481692, 0.0022506162276392009, 0.00224421891881164, 0.0022378005071541579, 0.0022313610530203358, 0.0022249006169616213, 0.0022184192597267598, 0.0022119170422612226, 0.0022053940257066341, 0.0021988502714001953, 0.0021922858408741103, 0.0021857007958550039, 0.0021790951982633439, 0.0021724691102128582, 0.0021658225940099497, 0.0021591557121531124, 0.0021524685273323408, 0.0021457611024285443, 0.0021390335005129517, 0.0021322857848465214, 0.002125518018879345, 0.0021187302662500516, 0.0021119225907852072, 0.002105095056498718, 0.0020982477275912257, 0.0020913806684495044, 0.0020844939436458561, 0.0020775876179375025, 0.0020706617562659762, 0.0020637164237565114, 0.0020567516857174285, 0.0020497676076395243, 0.0020427642551954514, 0.0020357416942391048, 0.0020286999908050002, 0.002021639211107653, 0.0020145594215409584, 0.0020074606886775633, 0.0020003430792682425, 0.0019932066602412713, 0.0019860514987017955, 0.0019788776619312, 0.0019716852173864759, 0.0019644742326995878, 0.0019572447756768373, 0.001949996914298224, 0.0019427307167168076, 0.0019354462512580664, 0.0019281435864192558, 0.0019208227908687633, 0.0019134839334454627, 0.0019061270831580673, 0.0018987523091844808, 0.0018913596808711472, 0.0018839492677323979, 0.0018765211394497986, 0.0018690753658714941, 0.0018616120170115511, 0.0018541311630493004, 0.0018466328743286767, 0.001839117221357557, 0.0018315842748070977, 0.0018240341055110701, 0.0018164667844651949, 0.0018088823828264734, 0.0018012809719125189, 0.0017936626232008873, 0.0017860274083284027, 0.0017783753990904859, 0.001770706667440478, 0.0017630212854889641, 0.0017553193255030958, 0.0017476008599059108, 0.0017398659612756523, 0.0017321147023450869, 0.00172434715600082, 0.0017165633952826111, 0.0017087634933826857, 0.0017009475236450492, 0.0016931155595647951, 0.0016852676747874155, 0.0016774039431081073, 0.0016695244384710795, 0.0016616292349688571, 0.0016537184068415843, 0.0016457920284763273, 0.0016378501744063736, 0.0016298929193105324, 0.0016219203380124312, 0.0016139325054798132, 0.0016059294968238317, 0.0015979113872983443, 0.0015898782522992046, 0.001581830167363554, 0.0015737672081691113, 0.0015656894505334602, 0.0015575969704133379, 0.0015494898439039192, 0.0015413681472381023, 0.0015332319567857911, 0.0015250813490531776, 0.0015169164006820224, 0.0015087371884489336, 0.0015005437892646454, 0.0014923362801732949, 0.001484114738351697, 0.0014758792411086194, 0.0014676298658840552, 0.001459366690248495, 0.0014510897919021973, 0.001442799248674458, 0.0014344951385228783, 0.0014261775395326322, 0.0014178465299157315, 0.0014095021880102909, 0.0014011445922797914, 0.0013927738213123423, 0.0013843899538199418, 0.0013759930686377377, 0.0013675832447232858, 0.0013591605611558068, 0.0013507250971354437, 0.0013422769319825164, 0.0013338161451367763, 0.0013253428161566585, 0.001316857024718535, 0.0013083588506159643, 0.0012998483737589413, 0.0012913256741731464, 0.0012827908319991929, 0.0012742439274918728, 0.0012656850410194028, 0.0012571142530626688, 0.001248531644214468, 0.0012399372951787519, 0.0012313312867698676, 0.0012227136999117976, 0.0012140846156373981, 0.0012054441150876388, 0.0011967922795108382, 0.0011881291902619004, 0.0011794549288015501, 0.0011707695766955664, 0.001162073215614016, 0.0011533659273304854, 0.0011446477937213111, 0.0011359188967648107, 0.001127179318540512, 0.0011184291412283803, 0.0011096684471080466, 0.001100897318558033, 0.0010921158380549794, 0.0010833240881728665, 0.0010745221515822403, 0.0010657101110494343, 0.0010568880494357914, 0.0010480560496968847, 0.0010392141948817376, 0.0010303625681320422, 0.001021501252681379, 0.0010126303318544326, 0.0010037498890662086, 0.00099486000782125035, 0.000985960771712852, 0.000977052264422274, 0.000968134569717955, 0.00095920777145472552, 0.00095027195357301789, 0.00094132720009807813, 0.00093237359513917537, 0.00092341122288881088, 0.00091444016762192663, 0.00090546051369511278, 0.00089647234554581445, 0.00088747574769153768, 0.00087847080472905467, 0.00086945760133360858, 0.00086043622225811676, 0.00085140675233237454, 0.000842369276462257, 0.00083332387962892066, 0.00082427064688800485, 0.00081520966336883123, 0.00080614101427360391, 0.00079706478487660782, 0.00078798106052340724, 0.00077888992663004326, 0.0007697914686822301, 0.000760685772234552, 0.00075157292290965836, 0.00074245300639745875, 0.00073332610845431689, 0.0007241923149022446, 0.000715051711628095, 0.00070590438458275424, 0.000696750419780334, 0.00068758990329736232, 0.00067842292127197454, 0.00066924955990310306, 0.00066006990544966674, 0.0006508840442297606, 0.00064169206261984314, 0.00063249404705392515, 0.00062329008402275629, 0.0006140802600730122, 0.00060486466180648092, 0.00059564337587924838, 0.00058641648900088371, 0.00057718408793362415, 0.00056794625949155926, 0.00055870309053981471, 0.00054945466799373574, 0.00054020107881806994, 0.00053094241002614993, 0.00052167874867907525, 0.00051241018188489433, 0.000503136796797785, 0.00049385868061723663, 0.00048457592058722917, 0.00047528860399541448, 0.0004659968181722958, 0.00045670065049040708, 0.00044740018836349264, 0.000438095519245686, 0.00042878673063068894, 0.00041947391005094992, 0.000410157145076843, 0.00040083652331584629, 0.00039151213241172064, 0.00038218406004368832, 0.00037285239392561214, 0.00036351722180517497, 0.00035417863146305982, 0.00034483671071213059, 0.00033549154739661435, 0.00032614322939128492, 0.00031679184460064856, 0.00030743748095813229, 0.0002980802264252762, 0.00028872016899093015, 0.00027935739667045705, 0.00026999199750494472, 0.00026062405956042922, 0.00025125367092713389, 0.00024188091971872981, 0.00023250589407162537, 0.00022312868214429782, 0.0002137493721166826, 0.00020436805218964659, 0.00019498481058458279, 0.000185599735543185, 0.00017621291532749251, 0.00016682443822034953, 0.00015743439252651389, 0.000148042866574808, 0.00013864994872198616, 0.00012925572735951552, 0.00011986029092546958, 0.00011046372792574376, 0.0001010661269730276, 9.1667576861366917e-05, 8.2268166716457269e-05, 7.2867986319027461e-05, 6.3467126859804421e-05, 5.4065682893940009e-05, 4.4663758128575342e-05, 3.52614859871987e-05, 2.5859124676461857e-05, 1.6457727579896869e-05, 7.07007641018259e-06 });
		}

		public GaussLegendreQuadrature(int n)
		{
			this.n = n;

			m = (n + 1) / 2;
			ComputeNodesCompactCached(n, m, out x, out w);
		}

		/// <summary>
		/// Computes the integral $\int_{-1}^1f(x)dx$ using n-point Gauss-Legendre quadrature.
		/// </summary>
		public double Integrate(Func<double, double> f)
		{
			double s;

			if (n % 2 == 0)
			{
				s = 0.0;
				for (int i = 0; i < m; i++)
				{
					s += w[i] * (f(x[i]) + f(-x[i]));
				}
			}
			else
			{
				s = w[0] * f(0.0);
				for (int i = 1; i < m; i++)
				{
					s += w[i] * (f(x[i]) + f(-x[i]));
				}
			}

			return s;
		}

		/// <summary>
		/// Computes the integral $\int_a^bf(x)dx$ using n-point Gauss-Legendre quadrature.
		/// </summary>
		public double Integrate(Func<double, double> f, double a, double b)
		{
			double c = 0.5 * (b - a);
			double d = 0.5 * (a + b);
			return c * Integrate(x => f(c * x + d));
		}

		/// <summary>
		/// Computes the integral $\int_{-1}^1f(x)dx$ using n-point Gauss-Legendre quadrature.
		/// </summary>
		public static double Integrate(Func<double, double> f, int n)
		{
			return new GaussLegendreQuadrature(n).Integrate(f);
		}

		/// <summary>
		/// Computes the integral $\int_a^bf(x)dx$ using n-point Gauss-Legendre quadrature.
		/// </summary>
		public static double Integrate(Func<double, double> f, double a, double b, int n)
		{
			return new GaussLegendreQuadrature(n).Integrate(f, a, b);
		}

		/// <summary>
		/// Computes the integral $\int_{-1}^1\int_{-1}^1f(x,y)dxdy$ using (n1,n2)-point nested double Gauss-Legendre quadrature.
		/// </summary>
		public static double Integrate(Func<double, double, double> f, int n1, int n2)
		{
			return GaussLegendreQuadrature.Integrate(y => GaussLegendreQuadrature.Integrate(x => f(x, y), n1), n2);
		}

		/// <summary>
		/// Computes the integral $\int_{a_1}^{b_1}\int_{a_2}^{b_2}f(x,y)dxdy$ using (n1,n2)-point nested double Gauss-Legendre quadrature.
		/// </summary>
		public static double Integrate(Func<double, double, double> f, double a1, double b1, double a2, double b2, int n1, int n2)
		{
			return GaussLegendreQuadrature.Integrate(y => GaussLegendreQuadrature.Integrate(x => f(x, y), a1, b1, n1), a2, b2, n2);
		}

		/// <summary>
		/// Computes the n-point Gauss-Legendre quadrature nodes such that $\int_{-1}^1f(x)dx\approxeq\sum_iw_if(x_i)$.
		/// </summary>
		public static void ComputeNodes(int n, out double[] x, out double[] w)
		{
			// Compute in compacted form.
			int m = (n + 1) / 2;
			double[] x0, w0;
			ComputeNodesCompactCached(n, m, out x0, out w0);

			// Expand to full form. These arrays are safe to return since they aren't referenced internally.
			x = new double[n];
			w = new double[n];
			if (n % 2 == 0)
			{
				for (int i = 0; i < m; i++)
				{
					x[2 * i] = -x0[i];
					x[2 * i + 1] = x0[i];
					w[2 * i] = w0[i];
					w[2 * i + 1] = w0[i];
				}
			}
			else
			{
				x[0] = 0.0;
				w[0] = w0[0];
				for (int i = 1; i < m; i++)
				{
					x[2 * i - 1] = -x0[i];
					x[2 * i] = x0[i];
					w[2 * i - 1] = w0[i];
					w[2 * i] = w0[i];
				}
			}
		}

		private static void ComputeNodesCompactCached(int n, int m, out double[] x, out double[] w)
		{
			Tuple<double[], double[]> xw;
			lock (nodes)
			{
				if (nodes.TryGetValue(n, out xw))
				{
					x = xw.Item1;
					w = xw.Item2;
					return;
				}
			}

			ComputeNodesCompact(n, m, out x, out w);

			// Store for small values of n.
			if (n <= 1024)
			{
				lock (nodes)
				{
					nodes[n] = Tuple.Create<double[], double[]>(x, w);
				}
			}
		}

		private static void ComputeNodesCompact(int n, int m, out double[] x, out double[] w)
		{
			if (n < 1)
			{
				throw new ArgumentException("Invalid number of nodes.");
			}

			// Verified to be in agreement with high-precision precomputed values for n = 2,3,...,64,96,100,128,256,512,1024
			// with errors smaller than 5e-16 (absolutely, both abscissa and weights).
			// http://processingjs.nihongoresources.com/bezierinfo/resources/lgvalues-abscissa.txt
			// http://processingjs.nihongoresources.com/bezierinfo/resources/lgvalues-weights.txt

			// The roots are symmetric in the interval, so we only have to find and store half of them.
			x = new double[m];
			w = new double[m];

			double t0 = (1.0 - (1.0 - 1.0 / n) / (8.0 * n * n));
			double t1 = 1.0 / (4.0 * n + 2.0);

			for (int i = 1; i <= m; i++)
			{
				// Find i'th root of Legendre polynomial.
				double x1, dx, w1, dw;

				// Initial guess (the weight isn't used).
				double x0 = Math.Cos(Math.PI * (4.0 * i - 1.0) * t1) * t0;
				double w0 = 0.0;

				// Newton iterations, at least one.
				int k = 0;
				do
				{
					// Compute Legendre polynomial value at x0.
					double p1 = 1.0;
					double p0 = x0;

					for (int j = 2; j <= n; j++)
					{
						double p2 = p1;
						p1 = p0;
						double t2 = x0 * p1;
						double t3 = (j - 1.0) / j;

						p0 = t2 + t3 * (t2 - p2);
					}

					// Compute Legendre polynomial derivative at x0.
					double dpdx = ((x0 * p0 - p1) * n) / (x0 * x0 - 1.0);

					// Newton step.
					x1 = x0 - p0 / dpdx;

					// Weight computing.
					w1 = 2.0 / ((1.0 - x1 * x1) * dpdx * dpdx);

					// Compute weight w0 on first iteration, needed for dw.
					if (k == 0)
					{
						w0 = 2.0 / ((1.0 - x0 * x0) * dpdx * dpdx);
					}

					dx = x0 - x1;
					dw = w0 - w1;

					x0 = x1;
					w0 = w1;
				} while ((dx != 0.0 || dw != 0.0) && ++k < 20);

				x[m - i] = x1;
				w[m - i] = w1;
			}
		}
	}
}
